<template>
  <div :class="attrConfigClass">
    <el-tabs class="attrTabs" stretch v-model="tabsActive">
      <el-tab-pane label="检验模板信息" name="1" v-if="showTemplateInfo">
        <el-form ref="form" label-position="right" :model="dataJson" label-width="80px" size="mini" class="attr-config">
          <el-form-item label="模板名称">
            <el-input disabled v-model="dataJson.name"> </el-input>
          </el-form-item>
          <el-form-item label="模板类型">
            <el-input disabled v-model="dataJson.type"> </el-input>
          </el-form-item>
          <el-form-item label="模板宽度">
            <el-input-number disabled v-model="dataJson.tableTotalWidth"> </el-input-number>
          </el-form-item>
        </el-form>
      </el-tab-pane>
      <template v-if="!showTemplateInfo">
        <el-tab-pane name="1" label="配置">
          <el-form ref="form" label-position="right" :model="cellInfo" label-width="80px" size="mini" class="attr-config">
            <el-form-item label="坐标">
              <el-input disabled v-model="crood"> </el-input>
            </el-form-item>
            <el-form-item label="宽度" v-if="cellInfo.style && cellInfo.style.width">
              <el-input-number :disabled="disableCellWidthAndHeight(cellInfo)" v-model="cellInfo.style.width" @change="handleChangeCellWidth" :min="0" controls-position="right">
              </el-input-number>
            </el-form-item>
            <el-form-item label="高度" v-if="cellInfo.style && cellInfo.style.height">
              <el-input-number
                :disabled="disableCellWidthAndHeight(cellInfo)"
                v-model="cellInfo.style.height"
                @change="handleChangeCellHeight"
                :min="0"
                controls-position="right"
              >
              </el-input-number>
            </el-form-item>
            <el-form-item label="类型">
              <el-select v-model="cellInfo.type" placeholder="请选择" @change="handleChangeType">
                <el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="影响字段" v-if="cellInfo.type == 'btnAddRow' || cellInfo.type == 'btnDeleteRow'">
              <el-input v-model="cellInfo.btnAddRowField" @change="handleChangeBtnAddRowField"> </el-input>
            </el-form-item>
            <el-form-item label="字典" v-if="cellInfo.type == 'select' || cellInfo.type == 'radio' || cellInfo.type == 'checkbox'">
              <el-select v-model="cellInfo.dicCode" placeholder="请选择" @change="handleChangeDicData">
                <el-option v-for="item in dictJson" :key="item.code" :label="item.name" :value="item.code"> </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="锁定">
              <el-switch v-model="cellInfo.isLock" @change="handleChangeCellLock"> </el-switch>
            </el-form-item>
          </el-form>
        </el-tab-pane>
        <el-tab-pane name="2" label="数据">
          <el-form ref="form" label-position="right" :model="cellInfo" label-width="80px" size="mini" class="attr-config">
            <el-form-item label="数据类型">
              <el-select v-model="cellInfo.dataType" placeholder="请选择数据类型" @change="handleChangeDataType">
                <el-option label="静态数据" value="1"> </el-option>
                <!-- <el-option label="数据字典" value="2" disabled> </el-option> -->
                <el-option label="API接口" value="3"> </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="数据源配置" v-if="cellInfo.dataType == 3">
              <el-button type="primary" @click="handleOpenDataConfig">配置数据源</el-button>
            </el-form-item>
            <el-form-item label="数据转换器">
              <el-checkbox v-model="cellInfo.isForamtter" @change="handleChangeIsForamtter">数据转换器</el-checkbox>
              <el-button type="primary" @click="handleOpenDataFormatter">配置转换器</el-button>
            </el-form-item>
            <el-form-item label="值">
              <el-input :rows="10" :disabled="disableCellWidthAndHeight(cellInfo)" type="textarea" v-model="cellInfo.value" @input="handleInputValue"> </el-input>
            </el-form-item>
          </el-form>
        </el-tab-pane>
        <el-tab-pane name="3" label="交互" v-if="cellInfo.type == 'select' || cellInfo.type == 'radio' || cellInfo.type == 'checkbox' || cellInfo.type == 'uploadAttachment'">
          <el-form ref="form" label-position="right" :model="cellInfo" label-width="80px" size="mini" class="attr-config">
            <el-form-item label="数据切换时">
              <el-checkbox v-model="cellInfo.eventConfig.start" @change="(value) => handleChangeEvent(value, 'start')">启用</el-checkbox>
            </el-form-item>
            <el-form-item label="目标单元格">
              <el-select v-model="cellInfo.eventConfig.targetCell" filterable placeholder="请选择目标单元格" @change="(value) => handleChangeEvent(value, 'targetCell')">
                <el-option :label="item" :value="item" v-for="(item, index) in coordArray" :key="index"> </el-option>
              </el-select>
            </el-form-item>
          </el-form>
        </el-tab-pane>
        <div class="jsonContainer">
          <vue-json-editor mode="code" lang="zh" v-model="cellInfo" :expandedOnStart="true" :showBtns="false"></vue-json-editor>
        </div>
      </template>
    </el-tabs>

    <!-- 数据源配置 -->
    <el-dialog custom-class="dataConfigDialog" title="数据源配置" append-to-body :close-on-click-modal="false" :visible.sync="dataConfigDialog.visible" :fullscreen="true">
      <el-form ref="dataConfigForm" label-position="right" :rules="dataConfigDialog.rules" :model="dataConfigDialog.form" label-width="80px" size="mini" class="attr-config">
        <el-form-item label="API地址">
          <el-input v-model="dataConfigDialog.form.url" disabled> </el-input>
        </el-form-item>
        <el-form-item label="API名称" prop="url">
          <el-select v-model="dataConfigDialog.form.url" filterable placeholder="请选择API" @change="handleChangeApi">
            <el-option v-for="item in apiAllList" :key="item.url" :label="item.name" :value="item.url"> </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="请求参数" prop="query">
          <div class="jsonContainer">
            <vue-json-editor mode="code" lang="zh" v-model="dataConfigDialog.form.query" :expandedOnStart="true" :showBtns="false"></vue-json-editor>
          </div>
          <!-- <el-input :rows="20" type="textarea" v-model="dataConfigDialog.form.query"> </el-input> -->
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" icon="el-icon-circle-close" @click="handleCancelData">取 消</el-button>
        <el-button type="primary" size="small" icon="el-icon-circle-plus-outline" @click="handleSubmitData">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 转换器配置 -->
    <el-dialog custom-class="dataFormatterDialog" title="数据转换器" append-to-body :close-on-click-modal="false" :visible.sync="dataFormatterDialog.visible" :fullscreen="true">
      <el-form
        ref="dataFormatterForm"
        label-position="right"
        :rules="dataFormatterDialog.rules"
        :model="dataFormatterDialog.form"
        label-width="80px"
        size="mini"
        class="attr-config"
      >
        <el-form-item label="转换函数" prop="fn">
          <el-input :rows="20" type="textarea" v-model="dataFormatterDialog.form.fn"> </el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" icon="el-icon-circle-close" @click="handleCancelFormatterData">取 消</el-button>
        <el-button type="primary" size="small" icon="el-icon-circle-plus-outline" @click="handleSubmitFormatterData">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { mapGetters, mapState } from 'vuex';
import { typeList, letters } from './data.js';
import vueJsonEditor from 'vue-json-editor';
export default {
  components: { vueJsonEditor },
  inject: ['reload'],
  data() {
    return {
      showTemplateInfo: true,
      active: true,
      tabsActive: '1',
      typeList: typeList,
      letters: letters,
      dataConfigDialog: {
        visible: false,
        form: {
          url: '',
          // method: 'POST',
          query: ''
        },
        rules: {
          url: [{ required: true, message: '请输入接口地址', trigger: 'blur' }]
        }
      },
      dataFormatterDialog: {
        visible: false,
        form: {
          fn: ''
        },
        rules: {}
      }
    };
  },
  computed: {
    ...mapState({
      cellInfo: (state) => state.form.cellInfo,
      dataJson: (state) => state.form.dataJson,
      dictJson: (state) => state.form.dictJson,
      histroyData: (state) => state.form.histroyData,
      histroyIndex: (state) => state.form.histroyIndex,
      coordArray: (state) => state.form.coordArray,
      baseTableConfig: (state) => state.form.baseTableConfig,
      boxAreaXY: (state) => state.form.boxAreaXY,
      xAxisNum: (state) => state.form.xAxisNum,
      yAxisNum: (state) => state.form.yAxisNum,
      apiAllList: (state) => state.form.apiAllList
    }),
    disableCellWidthAndHeight(cellInfo) {
      return (cellInfo) => {
        if (!cellInfo.xName || cellInfo.merge[0] != 1 || cellInfo.merge[1] != 1) {
          return true;
        } else {
          return false;
        }
      };
    },
    crood() {
      if (this.cellInfo) {
        if (this.cellInfo.xName) {
          return this.cellInfo.xName + '' + this.cellInfo.y;
        } else {
          return '';
        }
      } else {
        return '';
      }
    },
    attrConfigClass() {
      return ['attrConfig', this.active ? 'active' : ''];
    }
  },
  methods: {
    handleChangeCellHeight(value) {
      const that = this;
      that.dataJson.rows[that.cellInfo.y - 1].height = value;
      for (let i = 0; i < that.dataJson.rows[that.cellInfo.y - 1].cells.length; i++) {
        const element = that.dataJson.rows[that.cellInfo.y - 1].cells[i];
        if (element.merge[0] > 1) {
          // 根据跨行重新计算出高度 this.cellInfo.y - 1===>this.cellInfo.y + element.merge[0]- 2;
          let newHeight =
            that.yAxisNum
              .filter((item, index) => {
                return index >= that.cellInfo.y - 1 && index <= that.cellInfo.y + element.merge[0] - 2;
              })
              .reduce((pre, cur) => {
                return pre + cur.height;
              }, 0) - 1;
          element.style.height = newHeight;
        } else {
          element.style.height = value;
        }
      }
      that.$store.commit('form/initAxis', {
        cellWidth: that.baseTableConfig.cellWidth,
        cellHeight: that.baseTableConfig.cellHeight,
        rowIndex: that.cellInfo.x - 1
      });
    },
    handleChangeCellWidth(value) {
      for (let i = 0; i < this.dataJson.rows.length; i++) {
        const element = this.dataJson.rows[i];
        element.cells[this.cellInfo.x - 1].style.width = value;
      }

      this.$store.commit('form/initAxis', {
        cellWidth: this.baseTableConfig.cellWidth,
        cellHeight: this.baseTableConfig.cellHeight,
        rowIndex: this.cellInfo.x - 1
      });
    },
    handleChangeCellLock(value) {
      let tdCell = this.dataJson.rows[this.cellInfo.y - 1].cells[this.cellInfo.x - 1];
      this.$set(tdCell, 'isLock', value);
      console.log(this.dataJson.rows, this.cellInfo);
    },
    handleInputValue(value) {
      this.dataJson.rows[this.cellInfo.y - 1].cells[this.cellInfo.x - 1].value = value;
    },
    handleChangeType(value) {
      this.dataJson.rows[this.cellInfo.y - 1].cells[this.cellInfo.x - 1].type = value;
      this.$set(this.dataJson.rows[this.cellInfo.y - 1].cells[this.cellInfo.x - 1], 'dicData', []);
      this.$set(this.dataJson.rows[this.cellInfo.y - 1].cells[this.cellInfo.x - 1], 'dicCode', '');
      this.$set(this.cellInfo, 'dicData', []);
      this.$set(this.cellInfo, 'dicCode', '');
    },
    handleChangeApi(value) {
      let find = this.apiAllList.find((item) => item.url == value);
      if (find) {
        this.dataConfigDialog.form.url = find.url;
        this.dataConfigDialog.form.method = find.httpMethod;
        let query = {
          apiCode: find.code,
          parameterDatas: JSON.parse(find.paramsJson)
        };
        // this.dataConfigDialog.form.query = JSON.stringify(query, null, 4);
        this.dataConfigDialog.form.query = query;
      } else {
        this.dataConfigDialog.form.url = '';
        this.dataConfigDialog.form.method = 'post';
        this.dataConfigDialog.form.query = {};
      }
      // this.dataJson.rows[this.cellInfo.y - 1].cells[this.cellInfo.x - 1].url = value;
    },
    handleChangeBtnAddRowField(value) {
      this.$set(this.dataJson.rows[this.cellInfo.y - 1].cells[this.cellInfo.x - 1], 'btnAddRowField', value);
      this.$set(this.cellInfo, 'btnAddRowField', value);
    },
    handleChangeDicData(value) {
      let findIndex = this.dictJson.findIndex((item) => item.code == value);
      if (findIndex > -1) {
        this.$set(this.dataJson.rows[this.cellInfo.y - 1].cells[this.cellInfo.x - 1], 'dicData', this.dictJson[findIndex].dictList);
        this.$set(this.dataJson.rows[this.cellInfo.y - 1].cells[this.cellInfo.x - 1], 'dicCode', value);
        this.$set(this.cellInfo, 'dicData', this.dictJson[findIndex].dictList);
        this.$set(this.cellInfo, 'dicCode', value);
        this.$forceUpdate();
      }
    },
    handleOpenDataConfig() {
      const that = this;
      let data = that.dataJson.rows[that.cellInfo.y - 1].cells[that.cellInfo.x - 1];
      that.dataConfigDialog.form.url = data.url;
      that.dataConfigDialog.form.method = data.method || 'POST';
      that.dataConfigDialog.form.query = data.query;
      that.dataConfigDialog.visible = true;
    },
    handleChangeDataType(value) {
      const that = this;
      let data = that.dataJson.rows[that.cellInfo.y - 1].cells[that.cellInfo.x - 1];
      data.dataType = value;
    },
    handleChangeIsForamtter(value) {
      const that = this;
      let data = that.dataJson.rows[that.cellInfo.y - 1].cells[that.cellInfo.x - 1];
      data.isForamtter = value;
      // if (value) {
      //   // 格式化value数据
      //   let fn = new Function('return ' + data.dataFormatter)();
      //   let newValue = fn(data.value);
      //   data.value = structuredClone(newValue);
      //   that.cellInfo.value = data.value;
      // }
    },
    handleCancelData() {
      this.$refs['dataConfigForm'].resetFields();
      this.dataConfigDialog.visible = false;
    },
    handleSubmitData() {
      const that = this;
      that.$refs['dataConfigForm'].validate((valid) => {
        if (!valid) return false;
        that.dataConfigDialog.visible = false;
        console.log(that.dataConfigDialog.form, ' that.dataConfigDialog.form');
        let data = that.dataJson.rows[that.cellInfo.y - 1].cells[that.cellInfo.x - 1];
        data.url = that.dataConfigDialog.form.url;
        data.method = that.dataConfigDialog.form.method;
        let query = new Function('return ' + JSON.stringify(that.dataConfigDialog.form.query))();
        data.query = query;
        data.dataType = '3';
      });
    },
    handleOpenDataFormatter() {
      const that = this;
      let data = that.dataJson.rows[that.cellInfo.y - 1].cells[that.cellInfo.x - 1];
      let fn = `function filter (data, params) {
          return data;
      }`;
      that.dataFormatterDialog.form.fn = data.dataFormatter || fn;
      that.dataFormatterDialog.visible = true;
    },
    handleSubmitFormatterData() {
      const that = this;
      let data = that.dataJson.rows[that.cellInfo.y - 1].cells[that.cellInfo.x - 1];
      data.dataFormatter = that.dataFormatterDialog.form.fn;
      that.dataFormatterDialog.visible = false;
      // if (data.isForamtter) {
      //   let fn = new Function('return ' + data.dataFormatter)();
      //   let newValue = fn(data.value);
      //   data.value = structuredClone(newValue);
      //   that.cellInfo.value = data.value;
      // }
    },
    handleCancelFormatterData() {
      this.dataFormatterDialog.visible = false;
    },
    handleChangeEvent(value, property) {
      const that = this;
      let data = that.dataJson.rows[that.cellInfo.y - 1].cells[that.cellInfo.x - 1];
      this.$set(data, eventConfig[property], value);
    },
    toggleWidth() {
      this.active = !this.active;
    }
  }
};
</script>

<style lang="scss" scoped>
.attrConfig {
  position: absolute;
  top: 0;
  right: 0;
  width: 0;
  height: 100%;
  border-left: 0;
  padding: 0;
  box-sizing: border-box;
  overflow-y: scroll;
  background-color: #2d343c;
  transition: width 0.2s linear;
  &.active {
    border-left: 1px solid #282e3a;
    padding: 5px;
    width: 350px;
    transition: width 0.2s linear;
  }
  .el-tabs--border-card {
    border: 1px solid #282f3a;
  }
  ::v-deep .attrTabs {
    .el-tabs__nav-wrap {
      background-color: #13161a;
    }
    .el-tabs__item {
      background-color: #13161a;
      color: #fff;
      border: none;
      &.is-active {
        color: #409eff;
        background-color: #1d2126;
      }
    }
    .el-tabs__content {
      padding: 5px;
      background-color: #2d343c;
      color: #fff;
      .attr-config {
        .el-form-item__label {
          color: #fff;
          padding-right: 8px;
        }
        .el-input-number {
          width: 100%;
        }
        .el-select {
          width: 100%;
        }
      }
    }
  }
}
.jsonContainer {
  ::v-deep {
    /* jsoneditor右上角默认有一个链接,加css去掉 */
    .jsoneditor-poweredBy {
      display: none !important;
    }

    /*修改高度*/
    div.jsoneditor-outer {
      height: calc(100vh - 450px);
    }
    /*修改菜单栏背景颜色,原始背景为蓝色，为了和整体页面风格一致，改为黑色*/
    div.jsoneditor-menu {
      background-color: #000;
      border-bottom: 1px solid #000;
    }

    /*修改输入框边框颜色*/
    div.jsoneditor {
      border: 1px solid #000;
    }
  }
}
</style>
